#include "wifibot/wifibot.h"

namespace Lio {

// WifibotFilter - Class For The Application:
// FlatApplication - base class, provides all necessary windows routines
class WifibotFilter:public WifibotApplication
{
public:
	enum ChnlsDFTid{
		CHNL_DFT_FREQ,
		CHNL_DFT_IRL,
		CHNL_DFT_IRR,
		CHNL_AC_SHIFT,
		CHNL_AC_IRR,
		CHNL_AC_IRL,
		CHNL_DFT_COUNT};
protected:
	double df;
	int halfSize;
	FlatGraph fgDFT,fgAC;
	Channel *chnls[CHNL_DFT_COUNT];
	Vector<double>	freqs,dftIRL,dftIRR,acIRL,acIRR,acShift;
	void draw2D();
	//void updateAction();
	BOOL listenAction(WORD id, WORD code, void *info);
	void connectAction();
	BOOL createAction();
	void reshapeAction();
	void receiveAction();
	BOOL setBufferSize(int size);
} app;

BOOL WifibotFilter::setBufferSize(int size)
{
	if(WifibotApplication::setBufferSize(size))
	{
		halfSize=size/2+1;
		freqs.setSize(size,TRUE);
		dftIRL.setSize(size,TRUE);
		dftIRR.setSize(size,TRUE);
		acIRL.setSize(halfSize,TRUE);
		acIRR.setSize(halfSize,TRUE);
		acShift.setSize(halfSize,TRUE);
		
		chnls[CHNL_DFT_FREQ]->setSource(freqs.elems,-halfSize);
		chnls[CHNL_DFT_IRL]->setSource(dftIRL.elems,-halfSize);
		chnls[CHNL_DFT_IRR]->setSource(dftIRR.elems,-halfSize);
		chnls[CHNL_AC_SHIFT]->setSource(acShift);
		chnls[CHNL_AC_IRL]->setSource(acIRL);
		chnls[CHNL_AC_IRR]->setSource(acIRR);
		return TRUE;
	}
	return FALSE;
}
BOOL WifibotFilter::createAction()		
{
	name=_T("Wifibot Filter");

	fgDFT.copy(fgIR);
	fgDFT.stick(DIR_DOWN,0,40,&bConnect);
	fgDFT.chnlReadLines=2;
	chnls[CHNL_DFT_FREQ]=fgDFT.graph.addChannel(_T("f"));
	chnls[CHNL_DFT_IRL]=fgDFT.graph.addChannel(_T("DFT_IRL(f)"),_T("f"),INT_BLUE);
	chnls[CHNL_DFT_IRR]=fgDFT.graph.addChannel(_T("DFT_IRR(f)"),_T("f"),INT_RED);

	fgAC.copy(fgIR);
	fgAC.stick(DIR_RIGHT,10,0,&fgIR);
	fgAC.chnlReadLines=2;
	fgAC.graph.formatY.precision=5;
	fgAC.graph.marginChannel.y=55;
	chnls[CHNL_AC_SHIFT]=fgAC.graph.addChannel(_T("shift"));
	chnls[CHNL_AC_IRL]=fgAC.graph.addChannel(_T("autocorrel_IRL(shift)"),_T("shift"),INT_BLUE);
	chnls[CHNL_AC_IRR]=fgAC.graph.addChannel(_T("autocorrel_IRR(shift)"),_T("shift"),INT_RED);

	add(&fgDFT);
	add(&fgAC);

	return TRUE;
}
BOOL WifibotFilter::listenAction(WORD id, WORD code, void *info)
{
	return FALSE;
}
void WifibotFilter::reshapeAction()
{
	//fgDFT.size.copy(fgIR.size);
	fgIR.location.y=float(0.5*window.height+10);
	fgIR.size.set(float(0.55*window.width-20),float(0.5*window.height-20));
	fgAC.size.set(float(0.45*window.width-20),float(0.5*window.height-20));
	fgDFT.size.set(float(window.width-20),float(0.5*window.height-80));
}
void WifibotFilter::receiveAction()
{
	int i,j;
	double f=0,shift=0,tmpL,tmpR,tmpML1,tmpML2,tmpMR1,tmpMR2;
	getDFT(buffIRL.elems,dftIRL.elems,buffSize);
	getDFT(buffIRR.elems,dftIRR.elems,buffSize);
	df=INV(T);
	getAutoCorrelFunc(buffIRL.elems,buffSize,acIRL.elems,halfSize);
	getAutoCorrelFunc(buffIRR.elems,buffSize,acIRR.elems,halfSize);
	for(i=0;i<halfSize;i++)
	{
		freqs.elems[i]=f;
		f+=df;
		acShift.elems[i]=buffTime.elems[buffSize-1]-buffTime.elems[buffSize-1-i];
		tmpL=tmpR=tmpML1=tmpMR1=tmpML2=tmpMR2=0;
		for(j=buffSize-1;j>=i;j--)
		{
			tmpL+=buffIRL.elems[j]*buffIRL.elems[j-i];
			tmpR+=buffIRR.elems[j]*buffIRR.elems[j-i];
			tmpML1+=buffIRL.elems[j];
			tmpMR1+=buffIRR.elems[j];
			tmpML2+=buffIRL.elems[j-i];
			tmpMR2+=buffIRR.elems[j-i];
		}
		tmpL/=buffSize-i;
		tmpR/=buffSize-i;
		tmpML1/=buffSize-i;
		tmpMR1/=buffSize-i;
		tmpML2/=buffSize-i;
		tmpMR2/=buffSize-i;
		acIRL.elems[i]=tmpL-tmpML1*tmpML2;
		acIRR.elems[i]=tmpR-tmpMR1*tmpMR2;
	}
	fgDFT.graph.update();
	fgAC.graph.update();
}
void WifibotFilter::connectAction()
{
}
void WifibotFilter::draw2D()
{
	/*
	font.color=INT_BLACK;
	font.x=550;
	font.y=60;
	glPrint(&font,_T("Skirt: %.3f Hz"),skirtLength);
	*/
}

} // namespace Lio

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	return Lio::app.main(hInstance,hPrevInstance,lpCmdLine,nCmdShow);
}
